/************************************************************************
Copyright (c) 2010, 2013, C.R. All rights reserved. 

E-mail: crtoyou@gmail.com; crtoyou@163.com

You can redistribute it and/or modify it under the terms of the
GNU Lesser General Public License as published by the
Free Software Foundation version 3 of the License.

This source code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. if not, write to the Free Software Foundation, Inc., 
51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
************************************************************************/

#pragma once

#include <string>

inline void url_encode(std::string& url, const std::string & str, const char* exclude = NULL)
{
	const char table[16] = {
		'0', '1', '2', '3', '4', '5', '6', '7', 
		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
	};

	url.clear();
	std::string::const_iterator it;
	for (it = str.begin(); it != str.end(); it++)
	{
		char ch = *it;
		if ( (ch >= 'a' && ch <= 'z')
			|| (ch >= 'A' && ch <= 'Z')
			|| (ch >= '0' && ch <= '9') )
		{
			url.append(1, ch);
		}
		else if (ch == ' ')
		{
			url.append(1, '+');
		}
		else
		{
			bool found = false;
			if (exclude)
			{
				for (int m=0; exclude[m] != 0; m++)
				{
					if (ch == exclude[m])
					{
						found = true;
						url.append(1, ch);
						break;
					}
				}
			}
			if (!found)
			{
				url.append(1, '%');
				url.append(1, table[(ch>>4)&0x0f]);
				url.append(1, table[ch&0x0f]);
			}
		}
	}
}

inline void url_decode(const std::string& url, std::string & str)
{
	const char table[16] = {
		'0', '1', '2', '3', '4', '5', '6', '7',
		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
	};

	str.clear();
	std::string::const_iterator it;
	for (it = url.begin(); it != url.end(); it++)
	{
		char ch = *it;
		if (ch == '+')
		{
			str.append(1, ' ');
		}
		else if (ch == '%')
		{
			char ch1;
			it++;
			if (it == url.end())
			{
				str.clear();
				break;
			}
			ch1 = *it | 0x20;
			if ((ch1 >= '0') && (ch1 <= '9'))
				ch = ch1 - '0';
			else if ((ch1 >= 'a') && (ch1 <= 'f'))
				ch = ch1 - 'a' + 10;
			else
			{
				str.clear();
				break;
			}
			ch <<= 4;
			it++;
			if (it == url.end())
			{
				str.clear();
				break;
			}
			ch1 = *it | 0x20;
			if ((ch1 >= '0') && (ch1 <= '9'))
				ch += ch1 - '0';
			else if ((ch1 >= 'a') && (ch1 <= 'f'))
				ch += ch1 - 'a' + 10;
			else
			{
				str.clear();
				break;
			}
			str.append(1, ch);
		}
		else
		{
			str.append(1, ch);
		}
	}
}
